/*
 * EncryptUtil.java
 *
 * Copyright 2012 the original author or authors(ninglong).
 *
 * Licensed under the web-geek, Version 1.0 (the "License");
 *
 */
package org.geek.common.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.geek.common.base.BaseException;

/**   
 * <p>Java 加解密工具类</p>
 * @author ninglong bhd2973@qq.com   
 * @version V1.0   
 */
public class EncryptUtil {

    private static final String UTF8 = "utf-8";
    
    //定义 加密算法,可用 DES,DESede,Blowfish
    private static final String ALGORITHM_DESEDE = "DESede";

    /**
     * <p>MD5数字签名</p>
     * @param src
     * @return
     */
    public static String md5Digest(String src){
        // 定义数字签名方法, 可用：MD5, SHA-1
        byte[] b;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			b = md.digest(src.getBytes(UTF8));
		} catch (Exception e) {
			throw new BaseException(e.getMessage());
		} 
        return byte2HexStr(b);
    }

    /**
     * <p>3DES加密</p>
     * @param src
     * @param key
     * @return
     */
    public static String desedeEncoder(String src, String key){
        byte[] b;
		try {
			SecretKey secretKey = new SecretKeySpec(build3DesKey(key), ALGORITHM_DESEDE);
			Cipher cipher = Cipher.getInstance(ALGORITHM_DESEDE);
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			b = cipher.doFinal(src.getBytes(UTF8));
		} catch (Exception e) {
			throw new BaseException(e.getMessage());
		}
        return byte2HexStr(b);
    }
    
    /**
     * <p>3DES解密</p>
     * @param dest
     * @param key
     * @return
     */
    public static String desedeDecoder(String dest, String key){
        byte[] b;
        String str = "";
		try {
			SecretKey secretKey = new SecretKeySpec(build3DesKey(key), ALGORITHM_DESEDE);
			Cipher cipher = Cipher.getInstance(ALGORITHM_DESEDE);
			cipher.init(Cipher.DECRYPT_MODE, secretKey);
			b = cipher.doFinal(str2ByteArray(dest));
			str = new String(b, UTF8);
		} catch (Exception e) {
			throw new BaseException(e.getMessage());
		}
        return str;
    }
    
    /**
     * <p>字节数组转化为16进制字符串</p>
     * @param b
     * @return
     */
    private static String byte2HexStr(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < b.length; i++) {
            String s = Integer.toHexString(b[i] & 0xFF);
            if (s.length() == 1) {
                sb.append("0");
            }
            sb.append(s.toLowerCase());
        }
        return sb.toString();
    }
    
    /**
     * <p>字符串转字节数组</p>
     * @param s
     * @return
     */
    private static byte[] str2ByteArray(String s) {
        int byteArrayLength = s.length()/2;
        byte[] b = new byte[byteArrayLength];
        for (int i = 0; i < byteArrayLength; i++) {
            byte b0 = (byte) Integer.valueOf(s.substring(i*2, i*2+2), 16).intValue();
            b[i] = b0;
        }
        return b;
    }
    
    /**
     * <p>构造3DES加解密方法key</p>
     * @param keyStr
     * @return
     */
    private static byte[] build3DesKey(String keyStr){
        byte[] key = new byte[24];
        byte[] temp;
		try {
			temp = keyStr.getBytes(UTF8);
		} catch (UnsupportedEncodingException e) {
			throw new BaseException(e.getMessage());
		}
        if (key.length > temp.length) {
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }
}